{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个实例中，我们使用tensorflow来实现一个简单的手写数字识别的网络，并用这个网络来做个\n",
    "简单的识别示例。\n",
    "\n",
    "首先导入一些用到的库。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:50.515650Z",
     "start_time": "2018-06-01T06:32:43.133728Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "tf.logging.set_verbosity(tf.logging.INFO)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:39:48.304594Z",
     "start_time": "2018-06-01T04:55:17.674707Z"
    }
   },
   "source": [
    "先来看看数据长什么样子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.075054Z",
     "start_time": "2018-06-01T06:32:50.518290Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING: Logging before flag parsing goes to stderr.\n",
      "W0916 16:19:56.901946 140388383463232 deprecation.py:323] From <ipython-input-2-a34a30334354>:1: read_data_sets (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n",
      "W0916 16:19:56.902927 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:260: maybe_download (from tensorflow.contrib.learn.python.learn.datasets.base) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please write your own downloading logic.\n",
      "W0916 16:19:56.903619 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:262: extract_images (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "W0916 16:19:57.071723 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:267: extract_labels (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.data to implement this functionality.\n",
      "W0916 16:19:57.073058 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:110: dense_to_one_hot (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use tf.one_hot on tensors.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:19:57.105042 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/learn/python/learn/datasets/mnist.py:290: DataSet.__init__ (from tensorflow.contrib.learn.python.learn.datasets.mnist) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use alternatives such as official/mnist/dataset.py from tensorflow/models.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(55000, 784)\n",
      "(55000, 10)\n",
      "(5000, 784)\n",
      "(5000, 10)\n",
      "(10000, 784)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets(\"./\", one_hot=True)\n",
    "\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T05:49:40.128071Z",
     "start_time": "2018-06-01T05:49:40.123888Z"
    }
   },
   "source": [
    "可以看到images里面有数量不等的图片，每张图片是28x28长度的一个一维向量，\n",
    "所以用的时候需要先给它还原成28x28的二维图片。labels中则是图片对应的数字的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.695746Z",
     "start_time": "2018-06-01T06:32:51.077167Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(8, 8))\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4, 4, idx + 1)\n",
    "    plt.axis('off')\n",
    "    plt.title('[{}]'.format(np.argmax(mnist.train.labels[idx])))\n",
    "    plt.imshow(mnist.train.images[idx].reshape((28, 28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，定义用于训练的网络，首先定义网络的输入。\n",
    "\n",
    "这里我们直接使用上面的数据作为输入，所以定义两个placeholder分别用于图像和lable数据，另外，定义一个bool类型的变量用于标识当前网络是否正在训练。\n",
    "\n",
    "为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，两个placeholder的第一个维度就是batchsize，因为我们这里还没有确定batchsize，所以第一个维度留空。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.706044Z",
     "start_time": "2018-06-01T06:32:51.698913Z"
    }
   },
   "outputs": [],
   "source": [
    "x = tf.placeholder(\"float\", [None, 784], name='x')\n",
    "y = tf.placeholder(\"float\", [None, 10], name='y')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "因为我们输入的是图片展开后的一维向量，所以第一步就需要先把一维向量还原为二维的图片。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.719298Z",
     "start_time": "2018-06-01T06:32:51.707730Z"
    }
   },
   "outputs": [],
   "source": [
    "x_image = tf.reshape(x, [-1, 28, 28, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:07:36.530623Z",
     "start_time": "2018-06-01T06:07:36.522665Z"
    }
   },
   "source": [
    "接下来，我们定义第一个卷积层，使用6个5X5的卷积核对输入数据进行卷积，\n",
    "padding方式选择valid，所以输出数据的宽高变为24x24,但是深度已经从原来的1变成了6。\n",
    "本层卷积的激活函数为relu。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.764292Z",
     "start_time": "2018-06-01T06:32:51.721295Z"
    }
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('conv1'):\n",
    "    C1 = tf.contrib.slim.conv2d(\n",
    "        x_image, 6, [5, 5], padding='VALID', activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来进行stride为2的最大池化，池化后，输出深度不变，但是长宽减半，所以输出变成了12x12,深度6."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.774112Z",
     "start_time": "2018-06-01T06:32:51.766784Z"
    }
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('pool1'):\n",
    "    S2 = tf.contrib.slim.max_pool2d(C1, [2, 2], stride=[2, 2], padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:10:16.678485Z",
     "start_time": "2018-06-01T06:10:16.671472Z"
    }
   },
   "source": [
    "接下来，我们定义第二个卷积层，使用16个5X5的卷积核对输入数据进行卷积，\n",
    "padding方式还是选择valid，输出8x8,深度为16，本层卷积的激活函数为relu。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.805912Z",
     "start_time": "2018-06-01T06:32:51.776959Z"
    }
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('conv2'):\n",
    "    C3 = tf.contrib.slim.conv2d(\n",
    "        S2, 16, [5, 5], padding='VALID', activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再进行一次stride为2的最大池化，输出为4x4,深度16。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.814748Z",
     "start_time": "2018-06-01T06:32:51.807560Z"
    }
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('pool2'):\n",
    "    S4 = tf.contrib.slim.max_pool2d(C3, [2, 2], stride=[2, 2], padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "池化后的数据是3维的，这里做一个拉平的操作，将3维数据展开到1维，然后送入两层全连接，全连接隐层中神经元个数分别为120，84。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.856740Z",
     "start_time": "2018-06-01T06:32:51.817287Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:19:57.868117 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/contrib/layers/python/layers/layers.py:1634: flatten (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use keras.layers.flatten instead.\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('fc1'):\n",
    "    S4_flat = tf.contrib.slim.flatten(S4)\n",
    "    C5 = tf.contrib.slim.fully_connected(\n",
    "        S4_flat, 120, activation_fn=tf.nn.relu)\n",
    "\n",
    "with tf.name_scope('fc2'):\n",
    "    F6 = tf.contrib.slim.fully_connected(C5, 84, activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:17:39.880958Z",
     "start_time": "2018-06-01T06:17:39.869797Z"
    }
   },
   "source": [
    "###### 对特征添加一个0.6的dropout，以40%的概率丢弃特征中的某些数据，\n",
    "这样可以提高网络的推广能力，减少过拟合的可能性。\n",
    "\n",
    "需要注意的是，dropout仅在训练的时候使用，验证的时候，需要关闭dropout，\n",
    "所以验证时候的keep_prob是1.0。\n",
    "\n",
    "dropout的输出最终送入一个隐层为10的全连接层，这个全连接层即为最后的分类器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:51.913419Z",
     "start_time": "2018-06-01T06:32:51.860766Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:19:58.248456 140388383463232 deprecation.py:506] From <ipython-input-11-413a88f1eb86>:3: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope('dropout'):\n",
    "    keep_prob = tf.placeholder(name='keep_prob', dtype=tf.float32)\n",
    "    F6_drop = tf.nn.dropout(F6, keep_prob)\n",
    "\n",
    "with tf.name_scope('fc3'):\n",
    "    logits = tf.contrib.slim.fully_connected(F6_drop, 10, activation_fn=None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义loss和用于优化网络的优化器。loss计算使用了sparse_softmax_cross_entropy_with_logits,\n",
    "这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为0.3。\n",
    "\n",
    ">试试看，增大减小学习率，换个优化器再进行训练会发生什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.084738Z",
     "start_time": "2018-06-01T06:32:51.915376Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:19:58.271229 140388383463232 deprecation.py:323] From <ipython-input-12-802b87a63fd8>:2: softmax_cross_entropy_with_logits (from tensorflow.python.ops.nn_ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "\n",
      "Future major versions of TensorFlow will allow gradients to flow\n",
      "into the labels input on backprop by default.\n",
      "\n",
      "See `tf.nn.softmax_cross_entropy_with_logits_v2`.\n",
      "\n",
      "I0916 16:19:58.290891 140388383463232 summary_op_util.py:66] Summary name Conv/weights:0 is illegal; using Conv/weights_0 instead.\n",
      "I0916 16:19:58.292494 140388383463232 summary_op_util.py:66] Summary name Conv/biases:0 is illegal; using Conv/biases_0 instead.\n",
      "I0916 16:19:58.294071 140388383463232 summary_op_util.py:66] Summary name Conv_1/weights:0 is illegal; using Conv_1/weights_0 instead.\n",
      "I0916 16:19:58.295535 140388383463232 summary_op_util.py:66] Summary name Conv_1/biases:0 is illegal; using Conv_1/biases_0 instead.\n",
      "I0916 16:19:58.296973 140388383463232 summary_op_util.py:66] Summary name fully_connected/weights:0 is illegal; using fully_connected/weights_0 instead.\n",
      "I0916 16:19:58.298326 140388383463232 summary_op_util.py:66] Summary name fully_connected/biases:0 is illegal; using fully_connected/biases_0 instead.\n",
      "I0916 16:19:58.299710 140388383463232 summary_op_util.py:66] Summary name fully_connected_1/weights:0 is illegal; using fully_connected_1/weights_0 instead.\n",
      "I0916 16:19:58.301208 140388383463232 summary_op_util.py:66] Summary name fully_connected_1/biases:0 is illegal; using fully_connected_1/biases_0 instead.\n",
      "I0916 16:19:58.302663 140388383463232 summary_op_util.py:66] Summary name fully_connected_2/weights:0 is illegal; using fully_connected_2/weights_0 instead.\n",
      "I0916 16:19:58.304593 140388383463232 summary_op_util.py:66] Summary name fully_connected_2/biases:0 is illegal; using fully_connected_2/biases_0 instead.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Conv/weights:0\n",
      "Conv/biases:0\n",
      "Conv_1/weights:0\n",
      "Conv_1/biases:0\n",
      "fully_connected/weights:0\n",
      "fully_connected/biases:0\n",
      "fully_connected_1/weights:0\n",
      "fully_connected_1/biases:0\n",
      "fully_connected_2/weights:0\n",
      "fully_connected_2/biases:0\n"
     ]
    }
   ],
   "source": [
    "cross_entropy_loss = tf.reduce_mean(\n",
    "    tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))\n",
    "\n",
    "l2_loss = tf.add_n([\n",
    "    tf.nn.l2_loss(w)\n",
    "    for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)\n",
    "])\n",
    "\n",
    "for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES):\n",
    "    print(w.name)\n",
    "    tf.summary.histogram(w.name, w)\n",
    "    \n",
    "total_loss = cross_entropy_loss + 7e-5 * l2_loss\n",
    "tf.summary.scalar('cross_entropy_loss', cross_entropy_loss)\n",
    "tf.summary.scalar('l2_loss', l2_loss)\n",
    "tf.summary.scalar('total_loss', total_loss)\n",
    "\n",
    "optimizer = tf.train.GradientDescentOptimizer(\n",
    "    learning_rate=0.1).minimize(total_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:25:56.449132Z",
     "start_time": "2018-06-01T06:25:56.438340Z"
    }
   },
   "source": [
    "需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布，\n",
    "要想看到概率分布，还需要做一下softmax。\n",
    "\n",
    "将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:39:50.010829Z",
     "start_time": "2018-06-01T06:39:49.997501Z"
    }
   },
   "outputs": [],
   "source": [
    "pred = tf.nn.softmax(logits)\n",
    "correct_pred = tf.equal(tf.argmax(y, 1), tf.argmax(logits, 1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "saver用于保存或恢复训练的模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:32:52.127795Z",
     "start_time": "2018-06-01T06:32:52.103115Z"
    }
   },
   "outputs": [],
   "source": [
    "batch_size = 100\n",
    "trainig_step = 2200\n",
    "\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:35:22.270272Z",
     "start_time": "2018-06-01T06:33:18.829198Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.552956, the validation accuracy is 0.908\n",
      "after 200 training steps, the loss is 0.191272, the validation accuracy is 0.9432\n",
      "after 300 training steps, the loss is 0.0912913, the validation accuracy is 0.9528\n",
      "after 400 training steps, the loss is 0.177988, the validation accuracy is 0.9622\n",
      "after 500 training steps, the loss is 0.122392, the validation accuracy is 0.9658\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:20:01.655760 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/training/saver.py:960: remove_checkpoint (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to delete files with this prefix.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 600 training steps, the loss is 0.0650574, the validation accuracy is 0.973\n",
      "after 700 training steps, the loss is 0.0940612, the validation accuracy is 0.9728\n",
      "after 800 training steps, the loss is 0.113135, the validation accuracy is 0.9732\n",
      "after 900 training steps, the loss is 0.0730563, the validation accuracy is 0.9738\n",
      "after 1000 training steps, the loss is 0.163386, the validation accuracy is 0.9748\n",
      "after 1100 training steps, the loss is 0.105701, the validation accuracy is 0.9782\n",
      "after 1200 training steps, the loss is 0.114309, the validation accuracy is 0.9798\n",
      "after 1300 training steps, the loss is 0.11381, the validation accuracy is 0.9802\n",
      "after 1400 training steps, the loss is 0.175632, the validation accuracy is 0.9834\n",
      "after 1500 training steps, the loss is 0.141994, the validation accuracy is 0.9826\n",
      "after 1600 training steps, the loss is 0.0368421, the validation accuracy is 0.9804\n",
      "after 1700 training steps, the loss is 0.0554962, the validation accuracy is 0.9824\n",
      "after 1800 training steps, the loss is 0.0886879, the validation accuracy is 0.9838\n",
      "after 1900 training steps, the loss is 0.100519, the validation accuracy is 0.9832\n",
      "after 2000 training steps, the loss is 0.0444827, the validation accuracy is 0.9828\n",
      "after 2100 training steps, the loss is 0.0738765, the validation accuracy is 0.9834\n",
      "the training is finish!\n",
      "the test accuarcy is: 0.9849\n"
     ]
    }
   ],
   "source": [
    "merged = tf.summary.merge_all()\n",
    "with tf.Session() as sess:\n",
    "\n",
    "    writer = tf.summary.FileWriter(\"logs/\", sess.graph)\n",
    "\n",
    "    sess.run(tf.global_variables_initializer())\n",
    "\n",
    "    #定义验证集与测试集\n",
    "    validate_data = {\n",
    "        x: mnist.validation.images,\n",
    "        y: mnist.validation.labels,\n",
    "        keep_prob: 1.0\n",
    "    }\n",
    "    test_data = {x: mnist.test.images, y: mnist.test.labels, keep_prob: 1.0}\n",
    "\n",
    "    for i in range(trainig_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _, loss, rs = sess.run(\n",
    "            [optimizer, cross_entropy_loss, merged],\n",
    "            feed_dict={\n",
    "                x: xs,\n",
    "                y: ys,\n",
    "                keep_prob: 0.6\n",
    "            })\n",
    "        writer.add_summary(rs, i)\n",
    "\n",
    "        #每100次训练打印一次损失值与验证准确率\n",
    "        if i > 0 and i % 100 == 0:\n",
    "            validate_accuracy = sess.run(accuracy, feed_dict=validate_data)\n",
    "            print(\n",
    "                \"after %d training steps, the loss is %g, the validation accuracy is %g\"\n",
    "                % (i, loss, validate_accuracy))\n",
    "            saver.save(sess, './model.ckpt', global_step=i)\n",
    "\n",
    "    print(\"the training is finish!\")\n",
    "    #最终的测试准确率\n",
    "    acc = sess.run(accuracy, feed_dict=test_data)\n",
    "    print(\"the test accuarcy is:\", acc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-06-01T06:58:16.766415Z",
     "start_time": "2018-06-01T06:58:15.918700Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "W0916 16:20:06.091167 140388383463232 deprecation.py:323] From /home/seraph/miniconda3/envs/tensorflow/lib/python3.6/site-packages/tensorflow/python/training/saver.py:1276: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n",
      "I0916 16:20:06.092515 140388383463232 saver.py:1280] Restoring parameters from ./model.ckpt-2100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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aQc8frMX7/PTpJKqUpm1etBhXnznda9aaSdV+Tzqe06r29da3rN8RfIrlgY8oiQiIgrBjpKIiChEqR163XK6uRvP8MZPenGH9wdZ+dpgcsrqkFdLreVra8334vHVOtiZOfSachlVqljLfa6dGNP7st+qZRZUgzPS32zoYe6+837u04H5OgxZ7cUlea8jPbSrtfzbyc978VE/n22lNR1h9t/81FarzMps28qL//vPx714v4p2V1GA6P56tpq13Oj/zKVCe/5amXgF04RHlERERCHYURIREYVgR0lERBSi1MxRao/9rOWnH3zCi0dtNpcBtB9in96fyrmGQ4/7JYWlU3HlHWbPC99b/6XAvNsLzO0Hq7/xY8rqtLfxPxEEANacujMw74EP/8OLG/5Zcpdb+Oclh7z+SmC+rZ/Yt9Krum5Ryuq0t5h3i5nP91/+E6vJ3d6wlhf+YPbDM1670Upred9PXlywM/jvrDTgESUREVEIdpREREQhSs3Q64Zb7bt+NKlgTjK/8R8neXHWhukprUeFRma45uVm9p09dit/V6TT4jNiHwo669fTfEt7x91BSsKfT+RYy792H+nFQ1bb0yONXzZP3SjJyy2W96zqxT2y7QsVOk/q78XNnuTdd4qS2bGttfzlMY/7lip70YPr7GmPaRvN00NGt7K/J/3a+u6w9mK/Z620B0ec6sUFi/+Iqb7pwm9+IiKiEOwoiYiIQqR16HXdFYd68Ttd/mOlvbppXy/O+jK1w61+c+82Z/3tVntAqf+S3l6cv3pNidWJHCcdNCswbVPBDmt591DzkOEMDr3GTFWsZf8+MHldrpWWuWM1UiWjmn2HlwX3dfTi90951IsLkGXla3b2zymr095obXf7gcy5Fczdr67880gvXnbIVitfRlUzVdbtKnP2801XvG3l61fN/I0caT9jAh+NXerFc08q3Xfw4RElERFRCHaUREREIdhREhERhUjrHGXGaWu9eJ8K2VbaS28c78VNkNrTvDM7tfPiUceYpw/kqf0w4KWPmlOpq+al7qklZOSdeJAXP9X4xcB8yyIeWZHx7U/RM1Lc/tf+fWv5svG9vHjplkZevOsl+444sVp5hHmyy4kH2w9r/3CfZ3xLZl6yx8zzrHy18Gtc6y6v8u2vXRTAtMHs57t4cW38YOfbts2LGz1ivp/f7nuQle/8ah+bBbUv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\n",
      "text/plain": [
       "<Figure size 576x576 with 16 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        final_pred, acc = sess.run(\n",
    "            [pred, accuracy],\n",
    "            feed_dict={\n",
    "                x: mnist.test.images[:16],\n",
    "                y: mnist.test.labels[:16],\n",
    "                keep_prob: 1.0\n",
    "            })\n",
    "        orders = np.argsort(final_pred)\n",
    "        plt.figure(figsize=(8, 8))\n",
    "        print(acc)\n",
    "        for idx in range(16):\n",
    "            order = orders[idx, :][-1]\n",
    "            prob = final_pred[idx, :][order]\n",
    "            plt.subplot(4, 4, idx + 1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}: [{}]-[{:.1f}%]'.format(\n",
    "                np.argmax(mnist.test.labels[idx]), order, prob * 100))\n",
    "            plt.imshow(mnist.test.images[idx].reshape((28, 28)))\n",
    "\n",
    "    else:\n",
    "        pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 测试集上最终效果"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
